#include "HttpConnection.h"
#include "LogicSystem.h"

HttpConnection::HttpConnection(boost::asio::io_context& ioc) : m_httpSocket(ioc)
{
}

// 监听读写事件
void HttpConnection::start()
{
	auto self = shared_from_this();
	boost::beast::http::async_read(m_httpSocket, m_buffer, m_request, [self](boost::beast::error_code ec, size_t bytesTransferred) {
		try {
			if (ec) {
				std::cout << "http read error is " << ec.what() << std::endl;
				return;
			}
			boost::ignore_unused(bytesTransferred);
			self->handleReq();
			self->checkDeadline();
		}
		catch (const std::exception& exp) {
			std::cout << "exception is " << exp.what() << std::endl;
		}
	});
}

// 超时检测
void HttpConnection::checkDeadline()
{
	auto self = shared_from_this();
	m_deadline.async_wait([self](boost::beast::error_code ec) {
		if (!ec) {
			// 检测到超时，直接断开连接
			self->m_httpSocket.close(ec);
		}
	});
}

// 处理请求
void HttpConnection::handleReq()
{
	// 设置http的版本
	m_response.version(m_request.version());
	// 设置为短连接
	m_response.keep_alive(false);
	if (m_request.method() == boost::beast::http::verb::get) {
		preParseGetParam();
		// 处理http的get请求
		bool success = LogicSystem::getInstance()->handleGet(m_getUrl, shared_from_this());
		// 请求失败，返回请求失败的响应报文
		if (!success) {
			m_response.result(boost::beast::http::status::not_found);
			m_response.set(boost::beast::http::field::content_type, "text/plain");
			boost::beast::ostream(m_response.body()) << "url not found......\r\n";
			writeResponse();
			return;
		}
		// 请求成功
		m_response.result(boost::beast::http::status::ok);
		m_response.set(boost::beast::http::field::server, "GateServer");
		writeResponse();
		return;
	}

	if (m_request.method() == boost::beast::http::verb::post) {
		// 处理http的get请求
		bool success = LogicSystem::getInstance()->handlePost(m_request.target(), shared_from_this());
		// 请求失败，返回请求失败的响应报文
		if (!success) {
			m_response.result(boost::beast::http::status::not_found);
			m_response.set(boost::beast::http::field::content_type, "text/plain");
			boost::beast::ostream(m_response.body()) << "url not found......\r\n";
			writeResponse();
			return;
		}
		// 请求成功
		m_response.result(boost::beast::http::status::ok);
		m_response.set(boost::beast::http::field::server, "GateServer");
		writeResponse();
		return;
	}
}

// 返回的应答
void HttpConnection::writeResponse()
{
	auto self = shared_from_this();
	m_response.content_length(m_response.body().size());
	boost::beast::http::async_write(m_httpSocket, m_response, [self](boost::beast::error_code ec, std::size_t bytesTransfered) {
		// 关闭服务器的写端
		self->m_httpSocket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
		// 取消定时器
		self->m_deadline.cancel(); 
	});
}

// 解析url
void HttpConnection::preParseGetParam()
{
	// 提取 URI  
	auto uri = m_request.target();
	// 查找查询字符串的开始位置（即 '?' 的位置）  
	auto query_pos = uri.find('?');
	if (query_pos == std::string::npos) {
		m_getUrl = uri;
		return;
	}

	m_getUrl = uri.substr(0, query_pos);
	std::string query_string = uri.substr(query_pos + 1);
	std::string key;
	std::string value;
	size_t pos = 0;
	while ((pos = query_string.find('&')) != std::string::npos) {
		auto pair = query_string.substr(0, pos);
		size_t eq_pos = pair.find('=');
		if (eq_pos != std::string::npos) {
			key = UrlDecode(pair.substr(0, eq_pos)); // 假设有 url_decode 函数来处理URL解码  
			value = UrlDecode(pair.substr(eq_pos + 1));
			m_getParams[key] = value;
		}
		query_string.erase(0, pos + 1);
	}
	// 处理最后一个参数对（如果没有 & 分隔符）  
	if (!query_string.empty()) {
		size_t eq_pos = query_string.find('=');
		if (eq_pos != std::string::npos) {
			key = UrlDecode(query_string.substr(0, eq_pos));
			value = UrlDecode(query_string.substr(eq_pos + 1));
			m_getParams[key] = value;
		}
	}
}

// 从16进制转为十进制
unsigned char FromHex(unsigned char x)
{
	unsigned char y;
	if (x >= 'A' && x <= 'Z') y = x - 'A' + 10;
	else if (x >= 'a' && x <= 'z') y = x - 'a' + 10;
	else if (x >= '0' && x <= '9') y = x - '0';
	else assert(0);
	return y;
}

// char 转为16进制
unsigned char ToHex(unsigned char x)
{
	return  x > 9 ? x + 55 : x + 48;
}

// 实现url编码
std::string UrlEncode(const std::string& str)
{
	std::string strTemp = "";
	size_t length = str.length();
	for (size_t i = 0; i < length; i++)
	{
		// 判断是否仅有数字和字母构成
		if (isalnum((unsigned char)str[i]) ||
			(str[i] == '-') ||
			(str[i] == '_') ||
			(str[i] == '.') ||
			(str[i] == '~'))
			strTemp += str[i];
		else if (str[i] == ' ') //为空字符
			strTemp += "+";
		else
		{
			// 其他字符需要提前加%并且高四位和低四位分别转为16进制
			strTemp += '%';
			strTemp += ToHex((unsigned char)str[i] >> 4);
			strTemp += ToHex((unsigned char)str[i] & 0x0F);
		}
	}
	return strTemp;
}

// url解码
std::string UrlDecode(const std::string& str)
{
	std::string strTemp = "";
	size_t length = str.length();
	for (size_t i = 0; i < length; i++)
	{
		// 还原+为空
		if (str[i] == '+') strTemp += ' ';
		// 遇到%将后面的两个字符从16进制转为char再拼接
		else if (str[i] == '%')
		{
			assert(i + 2 < length);
			unsigned char high = FromHex((unsigned char)str[++i]);
			unsigned char low = FromHex((unsigned char)str[++i]);
			strTemp += high * 16 + low;
		}
		else strTemp += str[i];
	}
	return strTemp;
}